﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.WebNemo.Data;

namespace blackhouse.WebNemo.Business.Groups {
    public class SplitColumns {

        #region Fields

        private IGroup group;
        private IDataAccess dataAccess;
        private TabData[] tabs;
        private SplitColumnsData[] columnsIntoTabs;
        private Dictionary<int, GroupColumn[]> editSplitColumns;
        private Func<GroupColumn, bool> filter;

        #endregion

        #region Properties

        private Dictionary<int, GroupColumn[]> EditSplitColumns {
            get {
                if (this.editSplitColumns == null)
                    this.editSplitColumns = this.GetEditSplitColumns();
                return this.editSplitColumns;
            }
        }

        public bool DividedIntoTabs {
            get {
                return this.TabCounts > 1;
            }
        }

        public int TabCounts {
            get {
                return this.tabs.Length;
            }
        }

        public bool HaveNotAssignedColumns {
            get {
                return this.EditSplitColumns.ContainsKey(-1);
            }
        }

        public Func<GroupColumn, bool> Filter {
            get { return this.filter; }
            set { this.filter = value; }
        }

        #endregion

        #region Constructors

        public SplitColumns(IGroup group, IDataAccess dataAccess) {
            this.group = group;
            this.dataAccess = dataAccess;

            this.SetInstance();
        }

        #endregion

        #region Methods

        private Dictionary<int, GroupColumn[]> GetEditSplitColumns() {
            Dictionary<int, GroupColumn[]> editSplitCols = new Dictionary<int, GroupColumn[]>();
            GroupExtension extension = GroupExtension.GetGroupExtension(this.group);
            var allEditColumns = this.group.Columns.Where(gc => extension.ShouldUseThisColumnInEditor(gc));

            if (this.Filter != null)
                allEditColumns = allEditColumns.Where(this.Filter);

            for (int xt = 0; xt < this.TabCounts; xt++) {
                int tabId = this.tabs[xt].TabId;
                var tgc = from agc in allEditColumns
                          join sc in this.columnsIntoTabs on agc.ColumnId equals sc.ColumnId
                          where sc.TabId == tabId
                          orderby agc.ColumnSort, agc.ColumnName
                          select agc;
                GroupColumn[] editColumns = tgc.ToArray();
                if (editColumns.Length > 0) {
                    editSplitCols.Add(xt, editColumns);
                    allEditColumns = allEditColumns.Except(editSplitCols[xt]);
                }
            }
            
            if (allEditColumns.Count() > 0) // oznacza, że zostały kolumny bez przypisania
                editSplitCols.Add(-1, allEditColumns.ToArray());
            return editSplitCols;
        }

        private void SetInstance() {
            if (this.group.Exists)
                this.tabs = this.dataAccess.GetTabsForGroup(this.group.Id);
            else
                this.tabs = new TabData[0];

            if (this.tabs.Length > 0) {
                this.tabs = this.tabs.OrderBy(t => t.Sort).ToArray();
                this.columnsIntoTabs = this.dataAccess.GetColumnsSplit(this.group.Id);
            }
            else
                this.columnsIntoTabs = new SplitColumnsData[0];
        }

        public string GetTabName(int tabIdx) {
            if (tabIdx < this.tabs.Length)
                return this.tabs[tabIdx].TabName;
            else
                return string.Empty;
        }

        public GroupColumn[] GetNotAssignedEditColumns() {
            return this.GetEditColumns(-1);
        }

        public GroupColumn[] GetEditColumns(int tabIdx) {
            if (this.EditSplitColumns.ContainsKey(tabIdx))
                return this.EditSplitColumns[tabIdx];
            else
                return new GroupColumn[0];
        }

        #endregion

    }
}
